package team.dmh.wx.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import team.dmh.wx.entity.Friend;
import team.dmh.wx.entity.FriendRequest;
import team.dmh.wx.entity.User;
import team.dmh.wx.enums.FriendRequestTypeEnum;
import team.dmh.wx.enums.MsgOpsTypeEnum;
import team.dmh.wx.exception.ExceptionEnum;
import team.dmh.wx.exception.MyException;
import team.dmh.wx.mapper.FriendRequestMapper;
import team.dmh.wx.netty.ChatHandler;
import team.dmh.wx.netty.Content;
import team.dmh.wx.service.IFriendRequestService;
import team.dmh.wx.service.IFriendService;
import team.dmh.wx.service.IUserService;
import team.dmh.wx.util.IDUtils;
import team.dmh.wx.vo.FriendRequestVO;
import team.dmh.wx.vo.FriendVO;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hzk
 * @since 2018-10-15
 */
@Service
public class FriendRequestServiceImpl extends ServiceImpl<FriendRequestMapper, FriendRequest> implements IFriendRequestService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IFriendService friendService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean addFriend(String userId, String friendUsername) {
        User friendInfo = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, friendUsername));
        FriendRequest friendRequest = baseMapper.selectOne(new LambdaQueryWrapper<FriendRequest>().eq(FriendRequest::getSendUserId, userId).eq(FriendRequest::getAcceptUserId, friendInfo.getId()));
        if (friendRequest == null) {
            String id = IDUtils.getInstance().nextId();
            FriendRequest request = new FriendRequest().setId(id).setSendUserId(userId).setAcceptUserId(friendInfo.getId()).setRequestDateTime(LocalDateTime.now()).setStatus(FriendRequestTypeEnum.WAIT_TO_CONFIRM.type);
            baseMapper.insert(request);
            //获取接受者channel，推送消息进行好友请求列表的刷新
            Channel channel = ChatHandler.users.get(friendInfo.getId());
            if (ChatHandler.clients.contains(channel)) {
                if (channel != null) {
                    channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(new Content().setType(MsgOpsTypeEnum.PULL_FRIEND_REQUEST.type)
                    )));
                }
            }
        } else if (friendRequest.getStatus() == FriendRequestTypeEnum.WAIT_TO_CONFIRM.type || friendRequest.getStatus() == FriendRequestTypeEnum.IGNORE.type) {
            return false;
        } else {
            if (friendService.isExist(userId, friendInfo.getId())) {
                throw new MyException(ExceptionEnum.ALREADY_FRIEND);
            } else {
                Friend friend = new Friend().setFriendAlias(friendInfo.getNickname()).setId(String.valueOf(IDUtils.getInstance().nextId())).setFriendId(friendInfo.getId()).setUserId(userId);
                friendService.save(friend);
                Channel channel1 = ChatHandler.users.get(userId);
                FriendVO friendVO = friendService.getFriendInfo(userId, friendInfo.getId());
                if (ChatHandler.clients.contains(channel1)) {
                    if (channel1 != null) {
                        channel1.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(
                                new Content()
                                        .setType(MsgOpsTypeEnum.PULL_FRIEND.type)
                                        .setExtend(
                                                new FriendVO()
                                                        .setFriendId(friendVO.getFriendId())
                                                        .setFriendAlias(friendVO.getFriendAlias())
                                                        .setFriendImg(friendVO.getFriendImg())
                                                        .setFriendNickname(friendVO.getFriendNickname())
                                                        .setFriendUsername(friendVO.getFriendUsername())
                                                        .setFriendSignature(friendVO.getFriendSignature()))


                        )));
                    }
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public void ignore(String acceptUserId, String sendUserId) {
        baseMapper.update(new FriendRequest().setStatus(FriendRequestTypeEnum.IGNORE.type), new LambdaQueryWrapper<FriendRequest>().eq(FriendRequest::getAcceptUserId, acceptUserId).eq(FriendRequest::getSendUserId, sendUserId));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void pass(String acceptUserId, String sendUserId) {
        if (friendService.isExist(acceptUserId, sendUserId)) {
            throw new MyException(ExceptionEnum.ALREADY_FRIEND);
        }
        User acceptUser = userService.getById(acceptUserId);
        User sendUser = userService.getById(sendUserId);
        Friend friend = new Friend().setFriendAlias(sendUser.getNickname()).setId(String.valueOf(IDUtils.getInstance().nextId())).setFriendId(sendUserId).setUserId(acceptUserId);
        Friend friendBack = new Friend().setFriendAlias(acceptUser.getNickname()).setId(String.valueOf(IDUtils.getInstance().nextId())).setFriendId(acceptUserId).setUserId(sendUserId);
        friendService.save(friend);
        friendService.save(friendBack);
        baseMapper.update(new FriendRequest().setStatus(FriendRequestTypeEnum.PASS.type), new LambdaQueryWrapper<FriendRequest>()
                .eq(FriendRequest::getAcceptUserId, acceptUserId)
                .eq(FriendRequest::getSendUserId, sendUserId));

    }


    @Override
    public List<FriendRequestVO> getFriendRequestVOList(String userId) {

        return baseMapper.getFriendRequestVOList(userId);
    }
}
